package com.nodecollege.cloud.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.nodecollege.cloud.common.UpmsConstants;
import com.nodecollege.cloud.common.constants.NCConstants;
import com.nodecollege.cloud.common.exception.UpmsException;
import com.nodecollege.cloud.common.model.NCResult;
import com.nodecollege.cloud.common.model.QueryVO;
import com.nodecollege.cloud.common.model.po.*;
import com.nodecollege.cloud.common.utils.NCUtils;
import com.nodecollege.cloud.dao.mapper.*;
import com.nodecollege.cloud.service.ConfigService;
import com.nodecollege.cloud.service.TenantService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

/**
 * 租户管理service
 *
 * @author LC
 * @date 2019/8/4 10:21
 */
@Service
public class TenantServiceImpl implements TenantService {

    @Autowired
    private UpmsTenantMapper upmsTenantMapper;

    @Autowired
    private UpmsUserMapper upmsUserMapper;

    @Autowired
    private UpmsOrgMapper upmsOrgMapper;

    @Autowired
    private UpmsRoleMapper upmsRoleMapper;

    @Autowired
    private UpmsMemberMapper upmsMemberMapper;

    @Autowired
    private UpmsOrgMemberMapper upmsOrgMemberMapper;

    @Autowired
    private UpmsRoleMemberMapper upmsRoleMemberMapper;

    @Autowired
    private UpmsRoleOrgMapper upmsRoleOrgMapper;

    @Autowired
    private UpmsAppMapper upmsAppMapper;

    @Autowired
    private UpmsTenantAppMapper upmsTenantAppMapper;

    @Autowired
    private ConfigService configService;

    /**
     * 获取所有Tenant信息
     *
     * @param query
     * @return
     */
    @Override
    public NCResult<UpmsTenant> getTenantList(QueryVO<UpmsTenant> query) {
        List<UpmsTenant> list = new ArrayList<>();
        Long total = 0L;
        if (NCConstants.INT_NEGATIVE_1.equals(query.getPageSize())) {
            list = upmsTenantMapper.selectTenantListByMap(query.toMap());
            total = NCUtils.isNullOrEmpty(list) ? 0 : Long.parseLong(list.size() + "");
        } else {
            Page page = PageHelper.startPage(query.getPageNum(), query.getPageSize());
            if (query.isSort()) {
                page.setOrderBy(query.getSortKey() + " " + query.getSortDirection());
            }
            list = upmsTenantMapper.selectTenantListByMap(query.toMap());
            total = page.getTotal();
        }
        return NCResult.ok(list, total);
    }

    /**
     * 根据用户id查询租户列表
     *
     * @param queryVO
     * @return
     */
    @Override
    public NCResult<UpmsTenant> getTenantListByUserId(QueryVO<Long> queryVO) {
        List<UpmsTenant> list = new ArrayList<>();
        Long total = 0L;
        if (NCConstants.INT_NEGATIVE_1.equals(queryVO.getPageSize())) {
            list = upmsTenantMapper.selectTenantListByUserId(queryVO.getData());
            total = NCUtils.isNullOrEmpty(list) ? 0 : Long.parseLong(list.size() + "");
        } else {
            Page page = PageHelper.startPage(queryVO.getPageNum(), queryVO.getPageSize());
            if (queryVO.isSort()) {
                page.setOrderBy(queryVO.getSortKey() + " " + queryVO.getSortDirection());
            }
            list = upmsTenantMapper.selectTenantListByUserId(queryVO.getData());
            total = page.getTotal();
        }
        return NCResult.ok(list, total);
    }

    /**
     * 保存Tenant
     *
     * @param tenant
     * @return
     */
    @Override
    public void addTenant(UpmsTenant tenant) {

        NCUtils.nullOrEmptyThrow(tenant.getTenantCode(), new UpmsException("-1", "保存租户失败，租户代码必填！"));
        NCUtils.nullOrEmptyThrow(tenant.getTenantName(), new UpmsException("-1", "保存租户失败，租户名称必填！"));
        NCUtils.nullOrEmptyThrow(tenant.getCreateUserId(), new UpmsException("-1", "保存租户失败，创建用户id必填！"));
        UpmsUser upmsUser = upmsUserMapper.selectByPrimaryKey(tenant.getCreateUserId());
        NCUtils.nullOrEmptyThrow(upmsUser, new UpmsException("-1", "保存租户失败，创建者用户不存在！"));

        UpmsTenant query = new UpmsTenant();
        query.setTenantCode(tenant.getTenantCode());
        List<UpmsTenant> existTenants = upmsTenantMapper.selectTenantListByMap(new QueryVO<>(query).toMap());
        // tenant代码重复性检测
        NCUtils.notNullOrNotEmptyThrow(existTenants, new UpmsException("-1", "保存租户失败，该租户代码已存在！"));
        query.setTenantCode(null);
        query.setTenantName(tenant.getTenantName());
        existTenants = upmsTenantMapper.selectTenantListByMap(new QueryVO<>(query).toMap());
        // tenant名称重复性检测
        NCUtils.notNullOrNotEmptyThrow(existTenants, new UpmsException("-1", "保存租户失败，该租户名称已存在！"));
        tenant.setState(0);
        tenant.setCreateTime(new Date());
        upmsTenantMapper.insertSelective(tenant);

        // 默认租户为空，则设置新增租户为默认租户
        if (upmsUser.getTenantId() == null) {
            upmsUser.setTenantId(tenant.getTenantId());
            upmsUserMapper.updateByPrimaryKeySelective(upmsUser);
        }

        // 新建该租户的顶级组织机构
        UpmsOrg topOrg = new UpmsOrg();
        topOrg.setOrgCode(tenant.getTenantCode());
        topOrg.setOrgName(tenant.getTenantName());
        topOrg.setOrgType(0);
        topOrg.setParentId(0L);
        topOrg.setNum(0);
        topOrg.setState(0);
        topOrg.setTenantId(tenant.getTenantId());
        upmsOrgMapper.insertSelective(topOrg);

        // 新建该租户的新成员组织机构 租户新增成员默认组织机构
        UpmsOrg newMemberOrg = new UpmsOrg();
        newMemberOrg.setOrgCode(UpmsConstants.NEW_MEMBER_DEFALUT_ORG);
        newMemberOrg.setOrgName("新成员默认组织");
        newMemberOrg.setOrgType(0);
        newMemberOrg.setParentId(topOrg.getOrgId());
        newMemberOrg.setNum(0);
        newMemberOrg.setState(0);
        newMemberOrg.setTenantId(tenant.getTenantId());
        upmsOrgMapper.insertSelective(newMemberOrg);

        // 绑定新成员角色和新成员组织机构关系
        UpmsRole newMemberRole = new UpmsRole();
        newMemberRole.setRoleCode("newMemberDefaultRole");
        newMemberRole = upmsRoleMapper.selectListByMap(new QueryVO<>(newMemberRole).toMap()).get(0);

        UpmsRoleOrg newMemberRoleOrg = new UpmsRoleOrg();
        newMemberRoleOrg.setRoleId(newMemberRole.getRoleId());
        newMemberRoleOrg.setOrgId(newMemberOrg.getOrgId());
        newMemberRoleOrg.setTenantId(tenant.getTenantId());
        newMemberRoleOrg.setState(NCConstants.INT_0);
        upmsRoleOrgMapper.insert(newMemberRoleOrg);

        // 查询默认分配的应用信息
        UpmsConfig queryConfig = new UpmsConfig();
        queryConfig.setConfigType(NCConstants.INT_0);
        queryConfig.setConfigCode(UpmsConstants.DEFAULT_APPS);
        UpmsConfig defaultAppConfig = configService.getOne(queryConfig);
        List<String> apps = Arrays.asList(defaultAppConfig.getConfigValue().split(","));
        QueryVO queryApp = new QueryVO();
        queryApp.setStringList(apps);
        List<UpmsApp> defaultAppList = upmsAppMapper.selectListByMap(queryApp.toMap());

        // 绑定租户应用信息
        for (int i = 0; i < defaultAppList.size(); i++) {
            UpmsTenantApp tenantApp = new UpmsTenantApp();
            tenantApp.setAppId(defaultAppList.get(i).getAppId());
            tenantApp.setTenantId(tenant.getTenantId());
            tenantApp.setState(NCConstants.INT_1);
            upmsTenantAppMapper.insert(tenantApp);
        }

        // 查询该租户的超级管理员角色
        queryConfig.setConfigCode(UpmsConstants.DEFAULT_ROLES);
        UpmsConfig defaultRoleConfig = configService.getOne(queryConfig);
        List<String> roles = Arrays.asList(defaultRoleConfig.getConfigValue().split(","));
        QueryVO queryRole = new QueryVO();
        queryRole.setStringList(roles);
        List<UpmsRole> defaultRoleList = upmsRoleMapper.selectListByMap(queryRole.toMap());

        // 新建该租户的超级管理员
        UpmsMember superMember = new UpmsMember();
        superMember.setMemberAccount("admin");
        superMember.setMemberName(StringUtils.isBlank(upmsUser.getNickname()) ? upmsUser.getAccount() : upmsUser.getNickname());
        superMember.setUserId(tenant.getCreateUserId());
        superMember.setTenantId(tenant.getTenantId());
        superMember.setDefaultOrgId(topOrg.getOrgId());
        superMember.setDefaultRoleId(defaultRoleList.get(0).getRoleId());
        superMember.setState(0);
        superMember.setCreateTime(new Date());
        upmsMemberMapper.insertSelective(superMember);

        // 绑定超级管理员和顶级组织机构关系
        UpmsOrgMember orgMember = new UpmsOrgMember();
        orgMember.setOrgId(topOrg.getOrgId());
        orgMember.setMemberId(superMember.getMemberId());
        upmsOrgMemberMapper.insert(orgMember);

        for (int i = 0; i < defaultRoleList.size(); i++) {
            // 绑定超级管理员和分配角色关系
            UpmsRoleMember roleMember = new UpmsRoleMember();
            roleMember.setRoleId(defaultRoleList.get(i).getRoleId());
            roleMember.setMemberId(superMember.getMemberId());
            roleMember.setTenantId(tenant.getTenantId());
            roleMember.setState(NCConstants.INT_0);
            upmsRoleMemberMapper.insert(roleMember);

            // 绑定顶级组织机构和分配角色关系
            UpmsRoleOrg roleOrg = new UpmsRoleOrg();
            roleOrg.setRoleId(defaultRoleList.get(i).getRoleId());
            roleOrg.setOrgId(topOrg.getOrgId());
            roleOrg.setTenantId(tenant.getTenantId());
            roleOrg.setState(NCConstants.INT_0);
            upmsRoleOrgMapper.insert(roleOrg);
        }
    }

    /**
     * 更新tenant信息
     *
     * @param tenant
     * @return
     */
    @Override
    public void updateTenant(UpmsTenant tenant) {
        NCUtils.nullOrEmptyThrow(tenant.getTenantName(), new UpmsException("-1", "修改tenant失败，tenant Name必填！"));
        // 是否存在检测
        UpmsTenant existTenant = upmsTenantMapper.selectByPrimaryKey(tenant.getTenantId());
        NCUtils.nullOrEmptyThrow(tenant.getTenantName(), new UpmsException("-1", "修改tenant失败，该tenant不存在！"));

        UpmsTenant query = new UpmsTenant();
        query.setTenantCode(tenant.getTenantCode());
        List<UpmsTenant> existTenants = upmsTenantMapper.selectTenantListByMap(new QueryVO<>(query).toMap());
        // tenant代码重复性检测
        if (existTenants.size() == 1 && !existTenants.get(0).getTenantId().equals(existTenant.getTenantId())) {
            throw new UpmsException("-1", "保存tenant失败，该租户代码已存在！");
        }
        query.setTenantCode(null);
        query.setTenantName(tenant.getTenantName());
        existTenants = upmsTenantMapper.selectTenantListByMap(new QueryVO<>(query).toMap());
        // tenant名称重复性检测
        if (existTenants.size() == 1 && !existTenants.get(0).getTenantId().equals(existTenant.getTenantId())) {
            throw new UpmsException("-1", "保存tenant失败，该租户名称已存在！");
        }
        tenant.setState(existTenant.getState());
        upmsTenantMapper.updateByPrimaryKeySelective(tenant);
    }

    /**
     * 根据租户id查询租户数据
     *
     * @param upmsTenant
     * @return
     */
    @Override
    public UpmsTenant getTenantById(UpmsTenant upmsTenant) {
        NCUtils.nullOrEmptyThrow(upmsTenant.getTenantId(), new UpmsException("", "租户id不能为空！"));
        return upmsTenantMapper.selectByPrimaryKey(upmsTenant.getTenantId());
    }
}
